package com.cty._02_HighQualityCode._20_NumericStrings;

/**
 * @Auther: cty
 * @Date: 2020/7/6 10:06
 * @Description: 面试题20：表示数值的字符串
 * 题目：请实现一个函数用来判断字符串是否表示数值（包括整数和小数）。例如，
 * 字符串“+100”、“5e2”、“-123”、“3.1416”及“-1E-16”都表示数值，但“12e”、
 * “1a3.14”、“1.2.3”、“+-5”及“12e+5.4”都不是
 *
 * 一方面想要获取方法对变量修改后的值，另一方面又希望方法返回boolean类型的判断值时：
 *      1 使用静态方法实现，让返回值为boolean类型，通过全局静态变量传递变量
 *          测试的时候需要在外部不断地修改该静态变量，以测试不同的情况
 *      2 使用实例方法实现，让返回值为boolean类型，通过全局非静态变量传递变量
 *          该全局非静态变量可以通过构造器赋值，通过创建不同的对象便可以进行不同情况的测试，复用性好
 *
 * 使用String的方法时，必须保证不是空串！
 * @version: 1.0
 */
public class NumericStrings {

    private String str;

    public NumericStrings(String str){
        this.str = str;
    }

    public boolean isNumeric(){
        if(str==null || str.equals(""))
            return false;

        boolean numeric = scanInteger();  // 扫描整数部分

        if(!str.equals("") && str.charAt(0)=='.'){
            str = str.substring(1);
            numeric = scanUnsignedInteger() || numeric;  // 整数和小数部分至少有一个

            if(!str.equals("") && (str.charAt(0)=='e' || str.charAt(0)=='E')){
                str = str.substring(1);
                numeric = numeric && scanInteger();
            }
        }

        return numeric && str.equals("");
    }  // end isNumeric()

    /**
     * str起始是否存在若干整数
     * @return
     */
    private boolean scanInteger(){
        if(str.equals(""))
            return false;

        if(str.charAt(0)=='+' || str.charAt(0)=='-')
            str = str.substring(1);

        return scanUnsignedInteger();
    }  // end scanInteger()

    /**
     * str起始是否存在若干正整数
     * @return
     */
    private boolean scanUnsignedInteger(){
        if(str.equals(""))
            return false;

        int startLen = str.length();
        while(!str.equals("") && str.charAt(0)>='0' && str.charAt(0)<='9')
            str = str.substring(1);

        if(str.length() < startLen)
            return true;
        return false;
    }  // end scanUnsignedInteger()

}  // end class
